-
Notifications
You must be signed in to change notification settings - Fork 22
React 김준석 sprint8 #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React 김준석 sprint8 #81
The head ref may contain hidden characters: "React-\uAE40\uC900\uC11D-sprint8"
Conversation
1.css 파일이름 변경 2.color 변수이름 변경 3.스타일 속성위치 통합 및 변경
로그인 창에서 인풋요소 조건에 따른 알림문구 설정 회원가입 창에서 인풋요소 조건에 따른 알림 문구 설정 인터렉티브 JS 파일 추가
로그인 및 회원가입의 패스워드 칸 눈모양 클릭 시 암호화 여부 결정기능 추가
sprint5 시작하기에 앞서 기존 프로젝트에서 리액트를 추가하여 연결하는 작업을 진행 ROUTER 활용하여 연결 진행하였음
custom sort필터 구현 및 검색기능 구현
ul을 position:absolute로 변경하여 수정
기존 화살표 버튼에 적용 안되던 문제 해결
이미지 파일 인풋 컴포넌트 컨텐츠 입력 컴포넌트 구현
ALlItemList 안에 있던 개별아이템 출력 컴포넌트를 재사용성을 위해 분리
유지보수 및 재사용성 을 위한 컴포넌트 분리
좀 더 적절한 단어 사용
상태 통합 변수 네이밍 변경 컴포넌트 네이밍 변경 코드리팩터링
검색창 단어 입력 시 600ms 뒤 검색되며 1page로 이동되도록 설계
humonnom
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
첫 TS 과제인데, 잘 하셨습니다. 👍
몇가지 리뷰를 남겨두었으니 확인해주세요 :)
질문
auth페이지 formilk와 yup의 전체적인 flow를 공부하고 적용해보았습니다.
그리고 내부 동작구조를 좀 공부해보려고 github에서 코드를 좀 보다가 다시 넣어뒀는데, 원래 어려운건가요?
yup과 formik을 참고하셨다고 하셨는데, 해당 레포들의 코드를 보다가 어렵다고 느끼신걸까요?
라이브러리는 여러 추상화 레이어가 쌓여 있어서 처음에는 코드 읽기가 어려운게 맞습니다. 라이브러리는 예외처리도 꼼꼼하게 되어있는편이고요. 공부하시다보면 점점 읽기 쉬워집니다.
강사님은 어떤 라이브러리를 쓸 때 라이브러리의 내부logic을 전부 훓어보고 사용하시는지 전체적인 flow정도만 이해하고 사용하시는지 궁금합니다.
저는 레포를 처음부터 전체를 다 보는건 아니고, 저에게 필요한 부분의 파일만 보는 편입니다.
예를 들어 Formik 컴포넌트의 render props를 이해하고 싶어서 코드를 뜯어볼때, 관련 파일만 살펴봅니다. 관련 파일을 찾기 어려우시다면 AI의 도움을 받으시는 방법도 있습니다.
- 질문: 이 레포에서, Formik 컴포넌트의 render props를 공부하고 싶은데 어떤 파일 봐야하는지 알려줘
- github copilot 어시스티브 사용해서 질문
- 혹은 ai가 내장된 브라우저(예: Dia)를 사용하셔도 됩니다.
지금은 타입스크립트가 마냥 거추장스럽다고 느껴지네요. 강사님이 현업하시면서 실제로 TS덕에 개발이 수월하게 끝났다! 라는걸 체감하셨던 사례가 있으신지 궁금해요
그렇게 느껴지시는 것은 TS의 장점이 추상적이기 때문입니다.("타입 안정성"이나 "개발자 경험 향상") 그리고 JS를 익숙하게 쓰신다면 TS를 쓰면 더 시간이 오래걸리기 때문에 더 비효율적으로 느껴지기도 하죠.
그러나 현업에서는 정적 타입정보가 없이 작업하면 몇십배는 작업이 어려워집니다.
간단하게 정리하면 아래와 같습니다.
JS를 사용하면
-
코드 작성 단계에서 에러를 놓치게 되어 런타임 에러가 발생할 위험이 커집니다.(프로덕션 사이트가 예상치 못하게 터질 가능성 up)
-
복잡한 구조의 객체 활용시, 해당 객체의 속성 확인을 위해 파일을 이동해야하는 경우가 생깁니다.(user에 full_name이 있었는지? first_name과 last_name만 있는지?, friend_list가 배열인지 객체의 배열인지? 등)
TS를 사용하면
- 코드를 짤때 잘못된 타입 연산이나 존재하지 않는 속성에 접근("undefined에는 00속성이 없습니다."와 같은 에러) 등의 타입 실수를 하면 TypeError가 뜨므로 더 안정적인 코드 작성이 가능합니다.
- 타입 값이 있으면, 맥락 유추가 쉬워져서 AI 자동완성도 더 잘됩니다.
지금 TS가 왜 필요한지 잘 느껴지지 않는 것은 JS로 큰 불편없이 작업 가능한 규모의 프로젝트라서 그럴 수 있어요.
중급/심화 프로젝트에서는 기초 프로젝트보다 페이지 수가 많고 더 복잡한 프로젝트를 만들게되기 때문에 이때 감을 잡을 수 있으실거라고 생각이 되네요.
| `; | ||
|
|
||
| export default function ArticleList() { | ||
| const articleInfo: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(권장) 인라인 타입 대신 별도 interface로 정의하는 것이 더 가독성이 좋을 것 같네요.
그리고 articleInfo 자체도 정적인 값이기 때문에 컴포넌트 바깥에서 선언하는게 좋습니다.
interface ArticleInfo {
articleImg: string;
imgAlt: string;
articleTitle: string;
articleContent: string;
articleSubContent: string;
}
const articleInfo: ArticleInfo[] = [
{
articleImg: hotItem,
imgAlt: '판다 두마리가 옷구경하는 그림',
articleTitle: 'Hot item',
articleContent: '인기 상품을 확인해보세요',
articleSubContent:
'가장 HOT한 중고거래 물품을 판다 마켓에서 확인해 보세요',
},
{
articleImg: searchItem,
imgAlt: '돋보기 그림',
articleTitle: 'Search',
articleContent: '구매를 원하는 상품을 검색하세요',
articleSubContent: '구매하고 싶은 물품은 검색해서 쉽게 찾아보세요',
},
{
articleImg: registerItem,
imgAlt: '상품 고르는 그림',
articleTitle: 'Register',
articleContent: '판매를 원하는 상품을 등록하세요',
articleSubContent: '어떤 물건이든 판매하고 싶은 상품을 쉽게 등록하세요',
},
];There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
비교해놓고 보니 확실히 그러네요! 앞으로 이렇게 일관되게 적용해보겠습니다
| return ( | ||
| <List> | ||
| {articleInfo.map((article, index) => ( | ||
| <Article key={index} articleInfo={article} reverse={index == 1} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <Article key={index} articleInfo={article} reverse={index == 1} /> | |
| <Article key={article.articleTitle} articleInfo={article} reverse={index === 1} /> |
(필수) 기본적으로 엄격 비교를 사용하세요.(타입까지 검사됨)
(권장) index보다는 고유한 값을 써주는게 좋습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앞으로는 엄격한비교기준을 적용해보겠습니다.
해당 key를 index로 지정한 부분은 삭제나 추가될 일이 없어 순서가 밀릴일은 없다고 생각했습니다만, 확실히 고유key를 지정하는게 좋겠네요. 객체에 key항목을 만들어 적용해보겠습니다
| ...props | ||
| }: CustomInputProps) { | ||
| const [isVisible, setIsVisible] = useState<boolean>(false); | ||
| const [field, meta] = useField(props.name!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const [field, meta] = useField(props.name!); | |
| const [field, meta] = useField(props.name || ''); |
(필수) non-null assertion(!)보다는 해당 값이 없을때의 default value를 제공하는것이 더 안전합니다. (기본값 제공으로 타입 안정성 향상)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇군요 해당부분 참고하여 적용해보도록 하겠습니다.
| flex-direction: column; | ||
| `; | ||
|
|
||
| const CUSTOM_PROPS: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바뀌지 않는 상수 값이므로 컴포넌트 바깥에 선언하신 것은 잘 하셨습니다. 👍
(권장) 그런데 여기서도 인라인 타입 대신 별도 interface로 정의하는게 가독성이 더 좋을 것 같아요.
interface InputConfig {
label: string;
name: string;
type: string;
placeholder: string;
autoComplete: string;
forPassword?: boolean;
}
const CUSTOM_PROPS: InputConfig[] = [...]There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확실히 그렇네요 타입 따로 지정해보도록 하겠습니다.
| {({ isSubmitting, isValid, dirty }) => ( | ||
| <StyledForm> | ||
| {CUSTOM_PROPS.map((props, index) => ( | ||
| <CustomInput key={index} {...props} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <CustomInput key={index} {...props} /> | |
| <CustomInput key={props.name} {...props} /> |
(권장) key를 index 대신 고유한 값으로 변경해주세요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당부분 고유값 적용해보겠습니다.
| justify-content: center; | ||
| `; | ||
|
|
||
| interface location { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| interface location { | |
| interface LocationProps { |
(필수) interface 이름은 대문자로 시작해주세요.
Props 접미사를 추가하면 어떤 타입인지가 더 명확해집니다. (일관된 TypeScript 네이밍 컨벤션 사용하기)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앗 소문자가 들어갔네요 머쓱타드 대문자로 변경하겠습니다.
| width: 100%; | ||
| `; | ||
|
|
||
| const CUSTOM_PROPS: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서도 타입을 인라인 대신 인터페이스로 정의하고 사용하면 더 좋을 것 같은데, LoginForm.tsx와 타입이 겹치네요.
(필수) 공통 타입을 재사용해주세요. 공통으로 사용되는 타입은 types.ts 파일을 하나 만들어서 관리하면 돼요.
// types.ts 공통으로 사용하는 타입 정의
/**
* CustomInput 컴포넌트에 전달할 설정 객체의 타입
* LoginForm과 SignUpForm에서 공통으로 사용됨
*/
export interface InputConfig {
label: string;
name: string;
type: string;
placeholder: string;
autoComplete: string;
forPassword?: boolean;
}
// LoginForm.tsx와 SignUpForm.tsx에서 import해서 사용
import { InputConfig } from './types';There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오홍 타입관리 파일을 하나만들어서 export해보겠습니다
기본 요구사항
체크리스트 [기본]
네모 박스 안의 화면을 TypeScript로 마이그레이션해 주세요.
체크리스트 [심화]
any타입을 최소한으로 써주세요
추가사항
이전 미션 피드백 적용 (불필요한 optional chain삭제, 리팩토링 etc)
https://21-sprint-mission.vercel.app/
product쪽 도 틈틈이 TS 마이그레이션 진행해보겠습니다.
엄.. 아직 익숙한 느낌이 없네요
질문.
auth페이지 formilk와 yup의 전체적인 flow를 공부하고 적용해보았습니다.
그리고 내부 동작구조를 좀 공부해보려고 github에서 코드를 좀 보다가 다시 넣어뒀는데, 원래 어려운건가요?
강사님은 어떤 라이브러리를 쓸 때 라이브러리의 내부logic을 전부 훓어보고 사용하시는지 전체적인 flow정도만 이해하고 사용하시는지 궁금합니다.
지금은 타입스크립트가 마냥 거추장스럽다고 느껴지네요. 강사님이 현업하시면서 실제로 TS덕에 개발이 수월하게 끝났다! 라는걸 체감하셨던 사례가 있으신지 궁금해요